home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / gcc_260.zip / gcc_260 / cp / lib-except.c < prev    next >
C/C++ Source or Header  |  1994-05-06  |  5KB  |  204 lines

  1. /* terminate(), unexpected(), set_terminate(), set_unexpected()
  2.    as well as the default terminate func  and default unexpected func
  3.    ====================================================================== */ 
  4.  
  5. typedef void (*vfp)();
  6.  
  7. void
  8. __default_terminate()
  9. {
  10.  abort();
  11. }
  12.  
  13. void
  14. __default_unexpected()
  15. {
  16.  __default_terminate();
  17. }
  18.  
  19. static vfp __terminate_func = __default_terminate;
  20. static vfp __unexpected_func = __default_unexpected;
  21.  
  22. vfp
  23. set_terminate(func)
  24. vfp func;
  25. {
  26.  vfp old = __terminate_func;
  27.  
  28.  __terminate_func = func;
  29.  
  30.  return old;
  31. }
  32.  
  33. vfp
  34. set_unexpected(func)
  35. vfp func;
  36. {
  37.  vfp old = __unexpected_func;
  38.  
  39.  __unexpected_func = func;
  40.  
  41.  return old;
  42. }
  43.  
  44. void
  45. terminate()
  46. {
  47.  __terminate_func();
  48. }
  49.  
  50. void
  51. unexpected()
  52. {
  53.  __unexpected_func();
  54. }
  55. /* ====================================================================== */ 
  56.  
  57. typedef struct {
  58.     void *start;
  59.     void *end;
  60.     void *exception_handler;
  61.  } exception_table;
  62.  
  63. static int except_table_pos = 0;
  64. static void *except_pc = (void *)0;
  65. extern exception_table __EXCEPTION_TABLE__[];
  66.  
  67. /* this routine takes a pc, and the address of the exception handler associated
  68.    with the closest exception table handler entry associated with that PC,
  69.    or 0 if there are no table entries the PC fits in.  The algorithm works
  70.    something like this:
  71.  
  72.     while(current_entry exists) {
  73.         if(current_entry.start < pc )
  74.             current_entry = next_entry;
  75.         else {
  76.             if(prev_entry.start <= pc && prev_entry.end > pc) {
  77.                 save pointer to prev_entry;
  78.                 return prev_entry.exception_handler;
  79.              }
  80.             else return 0;
  81.          }
  82.      }
  83.     return 0;
  84.  
  85.    Assuming a correctly sorted table (ascending order) this routine should
  86.    return the tighest match...
  87.  
  88.    In the advent of a tie, we have to give the last entry, as it represents
  89.    an inner block.
  90.  */
  91.  
  92.  
  93. void *
  94. __find_first_exception_table_match(pc)
  95. void *pc;
  96. {
  97.   extern int printf(...);
  98.   exception_table *table = __EXCEPTION_TABLE__;
  99.   int pos = 0;
  100.   int best = 0;
  101. #if 0
  102.   printf("find_first_exception_table_match(): pc = %x!\n",pc);
  103. #endif
  104.  
  105.   except_pc = pc;
  106.  
  107. #if 0
  108.   /* We can't do this yet, as we don't know that the table is sorted.  */
  109.   do {
  110.     ++pos;
  111.     if (table[pos].start > except_pc)
  112.       /* found the first table[pos].start > except_pc, so the previous
  113.      entry better be the one we want! */
  114.       break;
  115.   } while(table[pos].exception_handler != (void*)-1);
  116.  
  117.   --pos;
  118.   if (table[pos].start <= except_pc && table[pos].end > except_pc)
  119.     {
  120.       except_table_pos = pos;
  121. #if 0
  122.       printf("find_first_eh_table_match(): found match: %x\n",table[pos].exception_handler);
  123. #endif
  124.       return table[pos].exception_handler;
  125.     }
  126. #else
  127.   while (table[++pos].exception_handler != (void*)-1) {
  128.     if (table[pos].start <= except_pc && table[pos].end > except_pc)
  129.       {
  130.     /* This can apply.  Make sure it is better or as good as the previous
  131.        best.  */
  132.     /* The best one ends first. */
  133.     if (best == 0 || (table[pos].end <= table[best].end
  134.               /* The best one starts last.  */
  135.               && table[pos].start >= table[best].start))
  136.       best = pos;
  137.       }
  138.   }
  139.   if (best != 0)
  140.     return table[best].exception_handler;
  141. #endif
  142.  
  143. #if 0
  144.   printf("find_first_eh_table_match(): else: returning NULL!\n");
  145. #endif
  146.   return (void*)0;
  147. }
  148.  
  149.  
  150. #if 0
  151. /* this routine returns the next tighest exception table match for the
  152.    current except_pc, or 0 if there aren't any wider entries (meaning
  153.    we need to either unwind a level and call
  154.    find_first_exception_table_match() with the new pc, or we need to
  155.    call terminate() because there are no more layers to unwind. */
  156.  
  157. void *
  158. __find_next_exception_table_match()
  159. {
  160.  exception_table *table = __EXCEPTION_TABLE__;
  161.  int pos = except_table_pos;
  162.  extern int printf(...);
  163.  
  164.  printf("__find_next_exception_table_match(): table = %x, pos = %d, except_pc = %x\n",table,pos,except_pc);
  165.  
  166.  if(! --pos) {
  167.      except_table_pos = 1;
  168.      return (void*)0;
  169.   }
  170.  
  171.  if(table[pos].start <= except_pc && table[pos].end >= except_pc) {
  172.      except_table_pos = pos;
  173.  printf("__find_next_exception_table_match(): found match: %x\n",table[pos].exception_handler);
  174.      return table[pos].exception_handler;
  175.   }
  176.  else {
  177.      except_table_pos = 1;
  178.      return (void*)0;
  179.   }
  180. }
  181. #endif
  182.  
  183. #if 0
  184. void
  185. __unwind_function(void *frameaddr)
  186. {
  187.  extern int printf(...);
  188.  
  189.  printf("__unwind_function(): frameaddr = %x\n",frameaddr);
  190. }
  191. #endif
  192.  
  193. int
  194. __throw_type_match (const char *catch_type, const char *throw_type)
  195. {
  196.  extern int printf(...);
  197.  
  198. #if 0
  199.  printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
  200.     catch_type, throw_type);
  201. #endif
  202.  return strcmp (catch_type, throw_type);
  203. }
  204.